package com.budwk.app.sqfwV2.generator.shawenTown.excel;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseExcelParamDTO;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.component.ShawenTownComponent;
import com.budwk.app.sqfwV2.dto.image.ExcelProblemImageConfigBO;
import com.budwk.app.sqfwV2.dto.shawenTown.SWTownProblemVo;
import com.budwk.app.sqfwV2.dto.shawenTown.ShawenTownSafetyPdfDTO;
import com.budwk.app.sqfwV2.dto.shawenTown.ShawenTownSafetyProblemVo;
import com.budwk.app.sqfwV2.enums.FileServiceConfigEnum;
import com.budwk.app.sqfwV2.enums.RectificateTimeEnum;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 小型生产经营场所“暨三合一场”消防安全排查台账
 * @since 2024-03-11
 */

@Slf4j
public class SmallPremisesInspectionGenerator extends BaseTemplateExcelGenerator {

    @Override
    protected String getTemplateName() {
        return FileServiceConfigEnum.BYB.getFilePath();
    }

    @Override
    public String getDownloadFileName() {
        return FileServiceConfigEnum.BYB.getFileName();
    }

    /**
     * 用户自定义excel基础参数，比如表头这样的公用数据
     * @param excelParam 已经填充的基础数据据
     * @param excelCreateParam excel生成提供的原料
     */
    @Override
    protected void customerPopularSheetBaseParam(Map<String, Object> excelParam, SqfwExcelCreateCommonBO excelCreateParam) {
        log.info("SmallPremisesInspectionGenerator getBaseExcelParamDTO: {}", JSONObject.toJSONString(excelCreateParam.getBaseExcelParamDTO()));
        BaseExcelParamDTO baseParam = excelCreateParam.getBaseExcelParamDTO();
        excelParam.put("district", formatStr(baseParam.getDistrict()));
        excelParam.put("county", formatStr(baseParam.getCounty()));
        excelParam.put("community", formatStr(baseParam.getCommunity()));
    }

    private String formatStr(String value) {
        if (StringUtils.isEmpty(value)) {
            return StringUtils.EMPTY;
        }
        if (CommonConstants.DIRECTLY_UNDER.equals(value)) {
            return StringUtils.EMPTY;
        }
        return value;
    }

    /**
     * 构造内容体
     * @param listMap
     * @param excelCreateParam
     */
    @Override
    protected void customerPopularSheetDataParam(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        List<Sqfw_formSummary_new> summaryList = DayingRoadPdfComponent.getSummaryList(listMap, excelCreateParam);
        log.info("SmallPremisesInspectionGenerator customerDataParam summaryList:  {}", JSONObject.toJSONString(summaryList));
        int num = 1;
        List<Sqfw_formSummary_new> newList = generateNewData(summaryList);
        // 获取消防安全问题默认值
        List<SWTownProblemVo> hazardsDefaults = ShawenTownComponent.getHazardsDefaults();
        for (Sqfw_formSummary_new summary : newList) {
            ShawenTownSafetyPdfDTO roadPdfDTO = JSONObject.parseObject(summary.getParamData(), ShawenTownSafetyPdfDTO.class);
            Map<String, Object> map = buildExcelMap(roadPdfDTO, hazardsDefaults);
            map.put("num", num ++);
            listMap.add(map);
        }
        log.info("SmallPremisesInspectionGenerator customerDataParam end: {}", JSONObject.toJSONString(listMap));
    }

    private Map<String, Object> buildExcelMap(ShawenTownSafetyPdfDTO roadPdfDTO, List<SWTownProblemVo> hazardsDefaults) {
        Map<String, Object> map = new HashMap<>();
        ShawenTownSafetyProblemVo small = roadPdfDTO.getSmallBusinessEstablishment();
        map.put("placeName", StrUtil.replaceNullStr(small.getPlaceName()));
        map.put("placeArea", StrUtil.replaceNullStr(small.getPlaceArea()));
        map.put("legalName", StrUtil.replaceNullStr(small.getLegalName()));
        map.put("legalMobile", StrUtil.replaceNullStr(small.getLegalMobile()));
        // 电动车隐患需加入“三合一场”台账，当电动车有隐患时，隐患值需存入“备注”中。
        map.put("remark", "");
        buildFire(roadPdfDTO, map, hazardsDefaults);
        buildBusinessLicense(map, small); // 营业执照图片
        buildLegalIdCardImage(map, small); // 法人身份证照
        map.put("checkedUnitLeader", ShawenTownComponent.getImage(roadPdfDTO.getCheckedUnitLeader())); // 签字
        return map;
    }

    private void buildLegalIdCardImage(Map<String, Object> map, ShawenTownSafetyProblemVo small) {
        // 初始化数据 法人身份证照：有图片贴图片，没有有图片写法人身份证号码；均没有写“无”
        map.put("legalIdCardImage", null);
        map.put("legalIdCardImageStr", StringUtils.EMPTY);
        String image = small.getLegalIdCardImage();
        if (StringUtils.isNotBlank(image)) {
            map.put("legalIdCardImage", CommonFormOfficeUtils.addPictureToByteList(image, 1));
            return;
        }
        if (StringUtils.isNotEmpty(small.getLegalIdCard())) {
            map.put("legalIdCardImageStr", small.getLegalIdCard());
            return;
        }
        map.put("legalIdCardImageStr", "无");
    }

    private void buildBusinessLicense(Map<String, Object> map, ShawenTownSafetyProblemVo small) {
        // 初始化数据 营业执照照片：有图片贴图片，没有图片写社会信用代码，都没有写“无”；
        map.put("businessLicensePhoto", null);
        map.put("businessLicensePhotoStr", StringUtils.EMPTY);
        String businessLicensePhoto = small.getBusinessLicensePhoto();
        if (StringUtils.isNotBlank(businessLicensePhoto)) {
            map.put("businessLicensePhoto", CommonFormOfficeUtils.addPictureToByteList(businessLicensePhoto, 1));
            return;
        }
        if (StringUtils.isNotEmpty(small.getSocialCreditCode())) {
            map.put("businessLicensePhotoStr", small.getSocialCreditCode());
            return;
        }
        map.put("businessLicensePhotoStr", "无");
    }

    private List<SWTownProblemVo> getLast(ShawenTownSafetyPdfDTO roadPdfDTO) {
        if (StringUtils.isEmpty(roadPdfDTO.getLastSummaryId())) {
            return null;
        }
        List<SWTownProblemVo> lastQxDatas = null;
        SqfwFormsummaryNewService sqfwFormsummaryNewService = NutzIocUtils.getBean(SqfwFormsummaryNewService.class);
        Sqfw_formSummary_new summaryNew = sqfwFormsummaryNewService.fetch(roadPdfDTO.getLastSummaryId());
        if (summaryNew != null) {
            ShawenTownSafetyPdfDTO lastPdf = JSONObject.parseObject(summaryNew.getParamData(), ShawenTownSafetyPdfDTO.class);
            List<SWTownProblemVo> fireIssues = lastPdf.getFireIssues();
            // 获取上一次期限整改的数据
            if (fireIssues != null && fireIssues.size() > 0) {
                lastQxDatas = fireIssues.stream().filter(e -> RectificateTimeEnum.DEADLINE_RECTIFICATION.getCode().equals(e.getRectificateType())).collect(Collectors.toList());
            }
        }
        return lastQxDatas;
    }

    private List<String> buildDanger(List<String> a1s, ShawenTownSafetyPdfDTO roadPdfDTO, List<SWTownProblemVo> lastQxData, List<Integer> zgList) {
        List<String> a1 = new ArrayList<>();
        List<SWTownProblemVo> fireIssues = roadPdfDTO.getFireIssues();
        for (String s : a1s) {
            // 检查当前问题是否存在隐患
            Optional<SWTownProblemVo> optional = fireIssues.stream().filter(e -> s.equals(e.getFields())).findFirst();
            if (optional.isPresent()) {
                // 存在隐患
                SWTownProblemVo swTownProblemVo = optional.get();
                a1.add(swTownProblemVo.getHazardDesc());
                zgList.add(2);
                continue;
            }
            // 不存在隐患
            if (lastQxData == null || lastQxData.size() == 0) {
                zgList.add(3);
                continue;
            }
            // 上次的数据有期限整改的，本次没有隐患 说明是已整改
            Optional<SWTownProblemVo> lastO = lastQxData.stream().filter(e -> s.equals(e.getFields())).findFirst();
            lastO.ifPresent(swTownProblemVo -> a1.add(swTownProblemVo.getHazardDesc()));
            zgList.add(1);
        }
        return a1;
    }

    private void buildFire(ShawenTownSafetyPdfDTO roadPdfDTO, Map<String, Object> map, List<SWTownProblemVo> hazardsDefaults) {
        map.put("facilities", CommonConstants.HORIAONTAL_LINE);
        map.put("electricalLaying", CommonConstants.HORIAONTAL_LINE);
        map.put("channel", CommonConstants.HORIAONTAL_LINE);
        map.put("accommodation", CommonConstants.HORIAONTAL_LINE);
        // 构建隐患详情
        // ¡当 未配备灭火器 / 灭火器被遮挡 / 灭火器过期、损坏、或压力不足；被选择时，将隐患对应项填入“消防设施器材”下；未选择则填“-”；
        // 获取上次的期限数据
        List<SWTownProblemVo> last = getLast(roadPdfDTO);
        // 整改情况记录
        List<Integer> zgList = Lists.newArrayList(); // 1 已整改  2： 有隐患   3：无隐患

        String s3 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "3").getFields();
        String s4 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "4").getFields();
        String s5 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "5").getFields();
        List<String> a1s = List.of(s3, s4, s5);

        String s1 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "1").getFields();
        String s2 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "2").getFields();
        List<String> a3s = List.of(s1, s2);

        List<String> a5s = new ArrayList<>();
        String s8 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "8").getFields();
        a5s.add(s8);
        a5s.addAll(ShawenTownComponent.getSevenDefaults().stream().map(SWTownProblemVo::getFields).collect(Collectors.toList()));

        List<String> a1 = buildDanger(a1s, roadPdfDTO, last, zgList);// 消防设施器材 未配备灭火器 / 灭火器被遮挡 / 灭火器过期、损坏、或压力不足

        String s6 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "6").getFields();
        List<String> a2 = buildDanger(List.of(s6), roadPdfDTO, last, zgList);// 电气线路敷设情况
        List<String> a3 = buildDanger(a3s, roadPdfDTO, last, zgList);// 通道情况

        String s7 = ShawenTownComponent.getElecProblemByNumber(hazardsDefaults, "7").getFields();
        List<String> a4 = buildDanger(List.of(s7), roadPdfDTO, last, zgList);// 住宿情况
        List<String> a5 = buildDanger(a5s, roadPdfDTO, last, zgList);//

        List<String> pcImages = new ArrayList<>();// 排查图片
        List<String> recAfterImages = new ArrayList<>(); // 整改图片
        getAllDangerPictures(roadPdfDTO, pcImages, recAfterImages);
        // 其他隐患
        buildOthers(roadPdfDTO, a5, last, zgList);
        // 解析电动车隐患
        map.put("issueStatus", buildIssueStatusStr(zgList));
        buildKey(a1, map, "facilities");
        buildKey(a2, map, "electricalLaying");
        buildKey(a3, map, "channel");
        buildKey(a4, map, "accommodation");
        buildKey(a5, map, "remark");
        // 整改图片
        map.put("recAfterImagesStr", null);
        map.put("recAfterImages", null);
        if (recAfterImages.size() > 0) {
            String join = String.join(",", recAfterImages);
            map.put("recAfterImages", CommonFormOfficeUtils.addPictureToByteList(join, 5));
        } else {
            map.put("recAfterImagesStr", "无");
        }
        // 排查图片
        buildPcImage(pcImages, map);
    }

    /**
     * 构建排查情况
     * 当当前所有问题隐患均为“已整改”时，需显示对应隐患值，且“排查情况”填“已整改”。当同时存在“已整改”及“现场/限期”时，排查情况为“有隐患”。只有全部没有问题时填写“无隐患”。
     * @return
     */
    private String buildIssueStatusStr(List<Integer> zgList) {
        Optional<Integer> any = zgList.stream().filter(e -> e == 2).findAny();
        if (any.isPresent()) {
            return "有隐患";
        }
        Optional<Integer> any1 = zgList.stream().filter(e -> e == 1).findAny();
        if (any1.isPresent()) {
            return "已整改";
        }
        return "无隐患";
    }

    private void buildImage(List<SWTownProblemVo> params, List<String> pcImages, List<String> recAfterImages) {
        if (params == null || params.size() == 0) {
            return;
        }
        for (SWTownProblemVo param : params) {
            if (pcImages.size() < 5) {
                if (StringUtils.isNotEmpty(param.getRiskImages())) {
                    String[] split = param.getRiskImages().split(",");
                    pcImages.addAll(List.of(split));
                }
            }
            if (recAfterImages.size() < 5) {
                if (StringUtils.isNotEmpty(param.getRectificationAfterPhoto())) {
                    String[] split = param.getRectificationAfterPhoto().split(",");
                    recAfterImages.addAll(List.of(split));
                }
            }
        }
    }

    // 获取所有的隐患图片
    private void getAllDangerPictures(ShawenTownSafetyPdfDTO roadPdfDTO, List<String> pcImages, List<String> recAfterImages) {
        ShawenTownSafetyProblemVo small = roadPdfDTO.getSmallBusinessEstablishment();
        if (small != null) {
            buildImage(small.getParams(), pcImages, recAfterImages);
            // 其他隐患
            List<SWTownProblemVo> otherDangers = small.getOtherDangers();
            if (otherDangers != null && otherDangers.size() > 0) {
                List<SWTownProblemVo> collect = otherDangers.stream().filter(e -> CommonConstants.TRUE.equals(e.getKey())).collect(Collectors.toList());
                buildImage(collect, pcImages, recAfterImages);
            }
        }
        ShawenTownSafetyProblemVo electricBicycle = roadPdfDTO.getElectricBicycle();
        if (electricBicycle != null) {
            buildImage(electricBicycle.getParams(), pcImages, recAfterImages);
        }
        // 取巡查图片
        if (pcImages.size() < 5) {
            if (StringUtils.isNotEmpty(roadPdfDTO.getVisitPictures())) {
                pcImages.addAll(List.of(roadPdfDTO.getVisitPictures().split(",")));
            }
        }
    }

    // 排查图片
    private void buildPcImage(List<String> pcImages, Map<String, Object> map) {
        map.put("visitPictures", null);
        map.put("visitPicturesStr", null);
        if (pcImages.size() > 0) {
            String join = String.join(",", pcImages);
            map.put("visitPictures", CommonFormOfficeUtils.addPictureToByteList(join, 5));
            return;
        }
        map.put("visitPicturesStr", "无");
    }

    private void buildKey(List<String> list, Map<String, Object> map, String columnKey) {
        if (list.size() == 0) {
            map.put(columnKey, CommonConstants.HORIAONTAL_LINE);
            return;
        }
        map.put(columnKey, String.join(";", list));
    }

    private void buildOthers(ShawenTownSafetyPdfDTO roadPdfDTO, List<String> as, List<SWTownProblemVo> lastQxDatas, List<Integer> zgList) {
        List<SWTownProblemVo> otherDangers = roadPdfDTO.getSmallBusinessEstablishment().getOtherDangers();
        if (otherDangers != null && otherDangers.size() > 0) {
            for (SWTownProblemVo paramDTO : otherDangers) {
                if (paramDTO.getKey().equals(CommonConstants.TRUE)) {
                    if (StringUtils.isNotEmpty(paramDTO.getHazardDesc())) {
                        as.add(paramDTO.getHazardDesc());
                        zgList.add(2);
                    }
                }
            }
        }
        // 判断该问题是否是已整改
        if (lastQxDatas == null) {
            zgList.add(3);
            return;
        }
        Optional<SWTownProblemVo> any = lastQxDatas.stream().filter(e -> StringUtils.isEmpty(e.getFields())).findAny();
        if (any.isEmpty()) {
            zgList.add(3);
            return;
        }
        // 上次问题是期限整改 本次是已整改的数据
        as.add(any.get().getHazardDesc());
        zgList.add(1);
    }

    @Override
    public List<Sqfw_formSummary_new> generateNewData(List<Sqfw_formSummary_new> summaryList) {
        if (CollectionUtil.isEmpty(summaryList)) {
            return summaryList;
        }
        List<Sqfw_formSummary_new> newList = new ArrayList<>();
        for (Sqfw_formSummary_new summary : summaryList) {
            ShawenTownSafetyPdfDTO roadPdfDTO = JSONObject.parseObject(summary.getParamData(), ShawenTownSafetyPdfDTO.class);
            // 是否有电动自行车 = 是 时生成表格
            ShawenTownSafetyProblemVo s = roadPdfDTO.getSmallBusinessEstablishment();
            if (s.getKey().equals(CommonConstants.TRUE)) {
                newList.add(summary);
            }
        }
        return newList;
    }

    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParam) {

    }

    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, SqfwExcelForSummaryBO forSummaryBO) {

    }

    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeErgodic(SqfwExcelCreateCommonBO excelCreateParam, Map<String, Object> excelParam) {
        return null;
    }

    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeCreate(Map<String, Object> excelParam) {
        return null;
    }

    @Override
    protected Class<?> getImageConfigBO() {
        return ExcelProblemImageConfigBO.class;
    }
}
